package com.zichan360.service;

import com.zichan360.domain.CompanyTransform;
import com.zichan360.exception.Exception404;
import com.zichan360.exception.message.CompanyException;
import com.zichan360.mapper.CompanyTransformMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * 创建用户:杨辽
 * 创建时间: 2018-03-14 12:08
 * 描   述:
 **/
@Service
public class CompanyService {

    private CompanyTransformMapper companyTransformMapper;

    @Autowired
    public CompanyService(CompanyTransformMapper companyTransformMapper) {
        this.companyTransformMapper = companyTransformMapper;
    }

    /*
    Reactor的类型
        Reactor有两种类型，Flux<T>和Mono<T>。Flux类似RaxJava的Observable，它可以触发零到多个事件，并根据实际情况结束处理或触发错误。

        Mono最多只触发一个事件，它跟RxJava的Single和Maybe类似，所以可以把Mono<Void>用于在异步任务完成时发出通知。

        因为这两种类型之间的简单区别，我们可以很容易地区分响应式API的类型：从返回的类型我们就可以知道一个方法会“发射并忘记”或“请求并等待”（Mono），还是在处理一个包含多个数据项的流（Flux）。

        Flux和Mono的一些操作利用了这个特点在这两种类型间互相转换。例如，调用Flux<T>的single()方法将返回一个Mono<T>，而使用concatWith()方法把两个Mono串在一起就可以得到一个Flux。
        类似地，有些操作对Mono来说毫无意义（例如take(n)会得到n>1的结果），而有些操作只有作用在Mono上才有意义（例如or(otherMono)）。


     Flux 和 Mono
        Flux 和 Mono 是 Reactor 中的两个基本概念。Flux 表示的是包含 0 到 N 个元素的异步序列。在该序列中可以包含三种不同类型的消息通知：正常的包含元素的消息、序列结束的消息和序列出错的消息。
        当消息通知产生时，订阅者中对应的方法 onNext(), onComplete()和 onError()会被调用。Mono 表示的是包含 0 或者 1 个元素的异步序列。该序列中同样可以包含与 Flux 相同的三种类型的消息通知。
        Flux 和 Mono 之间可以进行转换。对一个 Flux 序列进行计数操作，得到的结果是一个 Mono<Long>对象。把两个 Mono 序列合并在一起，得到的是一个 Flux 对象。


     */

    public Flux<CompanyTransform> list() {
        return Flux.fromIterable(this.companyTransformMapper.getCompanyTransformList());
    }

    public Mono<CompanyTransform> getById(Integer id) {
        return Mono.justOrEmpty(companyTransformMapper.getById(id)).switchIfEmpty(Mono.error(new Exception404()));
    }


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    public Mono<ServerResponse> list(ServerRequest request) {
        return ServerResponse.ok().body(list(), CompanyTransform.class).switchIfEmpty(Mono.error(new Exception404()));
    }

    public Mono<ServerResponse> getById(ServerRequest request) {
        return Mono.justOrEmpty(companyTransformMapper.getById(Integer.parseInt(request.pathVariable("id"))))
                .flatMap(user -> ServerResponse.ok().body(Mono.just(user), CompanyTransform.class))
//                .switchIfEmpty(ServerResponse.notFound().build());    //返回空
                .switchIfEmpty(Mono.error(new CompanyException()));     //返回自定义异常
    }


}
